/** @author Michael Floyd
 * @date March 9, 2007
 */

package rcscene;

import java.io.Serializable;

/** This class is used to store the weights that
 * will be used for each object type. This class
 * was created in order to more appropriately
 * store the weight data and to avoid the use
 * of an array.
 * 
 */

public class ObjectWeights implements Serializable{
	
	private static final long serialVersionUID = 1L;
	
	private float ballWeight;
	private float goalWeight;
	private float flagWeight;
	private float linesWeight;
	private float teamPlayerWeight;
	private float opponentPlayerWeight;
	private float unknownPlayerWeight;
	
	private int NUM_WEIGHTS = 7;
	private float WEIGHT_MIN = 0;
	private float WEIGHT_MAX = 1;
	
	
	/** Given an array of doubles (with a size equal to the number
	 *  of weights, NUM_WEIGHTS ), the weights will be set to the
	 *  values specified in the array. Currently, there are 7 weights
	 *  used. The weights will be assigned in the following order :
	 *  ball, goal, flag, lines, team player, opponent player, unknown player.
	 *  So weights[0] will be assigned to the ballWeight, and weight[6] will
	 *  be assigned to the unknownPlayerWeight.
	 * 
	 */
	public ObjectWeights(float[] weights){
		if(weights.length != NUM_WEIGHTS){
			throw new IllegalArgumentException("Invalid number of object weights " +
					"supplied. Expecting " + NUM_WEIGHTS + " given " + weights.length);
		}
		
		verifyRange(WEIGHT_MIN,WEIGHT_MAX,weights[0]);
		this.ballWeight = weights[0];
		verifyRange(WEIGHT_MIN,WEIGHT_MAX,weights[1]);
		this.goalWeight = weights[1];
		verifyRange(WEIGHT_MIN,WEIGHT_MAX,weights[2]);
		this.flagWeight = weights[2];
		verifyRange(WEIGHT_MIN,WEIGHT_MAX,weights[3]);
		this.linesWeight = weights[3];
		verifyRange(WEIGHT_MIN,WEIGHT_MAX,weights[4]);
		this.teamPlayerWeight = weights[4];
		verifyRange(WEIGHT_MIN,WEIGHT_MAX,weights[5]);
		this.opponentPlayerWeight = weights[5];
		verifyRange(WEIGHT_MIN,WEIGHT_MAX,weights[6]);
		this.unknownPlayerWeight = weights[6];
		
	}
	
	/** Default constructor. All weights will be set to their
	 *  minimum value (usually 0 ).
	 * 
	 */
	public ObjectWeights(){
		this.ballWeight = WEIGHT_MIN;
		this.goalWeight = WEIGHT_MIN;
		this.flagWeight = WEIGHT_MIN;
		this.linesWeight = WEIGHT_MIN;
		this.teamPlayerWeight = WEIGHT_MIN;
		this.opponentPlayerWeight = WEIGHT_MIN;
		this.unknownPlayerWeight = WEIGHT_MIN;
	}

	
	public float getBallWeight() {
		return ballWeight;
	}

	public void setBallWeight(float ballWeight) {
		verifyRange(WEIGHT_MIN,WEIGHT_MAX,ballWeight);
		this.ballWeight = ballWeight;
	}

	public float getFlagWeight() {
		return flagWeight;
	}

	public void setFlagWeight(float flagWeight) {
		verifyRange(WEIGHT_MIN,WEIGHT_MAX,flagWeight);
		this.flagWeight = flagWeight;
	}

	public float getGoalWeight() {
		return goalWeight;
	}

	public void setGoalWeight(float goalWeight) {
		verifyRange(WEIGHT_MIN,WEIGHT_MAX,goalWeight);
		this.goalWeight = goalWeight;
	}

	public float getLinesWeight() {
		return linesWeight;
	}

	public void setLinesWeight(float linesWeight) {
		verifyRange(WEIGHT_MIN,WEIGHT_MAX,linesWeight);
		this.linesWeight = linesWeight;
	}

	public float getOpponentPlayerWeight() {
		return opponentPlayerWeight;
	}

	public void setOpponentPlayerWeight(float opponentPlayerWeight) {
		verifyRange(WEIGHT_MIN,WEIGHT_MAX,opponentPlayerWeight);
		this.opponentPlayerWeight = opponentPlayerWeight;
	}

	public float getTeamPlayerWeight() {
		return teamPlayerWeight;
	}

	public void setTeamPlayerWeight(float teamPlayerWeight) {
		verifyRange(WEIGHT_MIN,WEIGHT_MAX,teamPlayerWeight);
		this.teamPlayerWeight = teamPlayerWeight;
	}

	
	public float getUnknownPlayerWeight() {
		return unknownPlayerWeight;
	}

	public void setUnknownPlayerWeight(float unknownPlayerWeight) {
		verifyRange(WEIGHT_MIN,WEIGHT_MAX,unknownPlayerWeight);
		this.unknownPlayerWeight = unknownPlayerWeight;
	}
	
	/** A method used by the weight setters to ensure the set weight
	 *  is within a specified range. 
	 *  @param min The minimum value of the weight
	 *  @param max The maximum value of the weight
	 *  @param value The weight that is being tested
	 *  @throws IllegalArgumentException If the weight is not
	 *  within the range.
	 */
	
	private void verifyRange(float min, float max, float value) 
										throws IllegalArgumentException{
		
		//ensure the minimum is less than the maximum
		if(min>max){
			float tmp = min;
			min = max;
			max = tmp;
		}
		if(value < min || value > max){
			throw new IllegalArgumentException("The weight must be " +
					"between " + min + " and " + max);
		}
	}
	
	public String toString(){
		return "[" + ballWeight + "," + goalWeight + "," + flagWeight + "," + 
				linesWeight + "," + teamPlayerWeight + "," + 
				opponentPlayerWeight + "," + unknownPlayerWeight + "]";
	}
}
